#include "Rational.h"
#include <cstdlib>

Rational operator+ (const Rational& a, const Rational& b)
{
	Rational t(a);
	t += b;
	return t;
}

Rational operator- (const Rational& a, const Rational& b)
{
	Rational t(a);
	t -= b;
	return t;
}

Rational operator- (const Rational& a)
{
	return Rational(-a.numerator(), a.denominator());
}

Rational operator* (const Rational& a, const Rational& b)
{
	Rational t(a);
	t *= b;
	return t;
}

Rational operator/ (const Rational& a, const Rational& b)
{
	Rational t(a);
	t /= b;
	return t;
}


Rational::Rational(int a, int b) :
	_numerator(a),
	_denominator(b)
{}

Rational::Rational(const Rational& a) :
	_numerator(a._numerator),
	_denominator(a._denominator)
{}

static int gcd(int a, int b)
{
	if (b == 0)
		return a;

	return gcd(b, a % b);
}

void Rational::reduce()
{
	int r = gcd(std::abs(_numerator), std::abs(_denominator));

	_numerator /= r;
	_denominator /= r;
}

Rational::operator double () const
{
	return double(_numerator) / _denominator;
}

Rational& Rational::operator= (const Rational& b)
{
	_numerator = b._numerator;
	_denominator = b._denominator;
	return *this;
}

Rational& Rational::operator+= (const Rational& b)
{
	_numerator = _numerator * b._denominator + b._numerator * _denominator;
	_denominator *= b._denominator;
	reduce();
	return *this;
}

Rational& Rational::operator-= (const Rational& b)
{
	_numerator = _numerator * b._denominator - b._numerator * _denominator;
	_denominator *= b._denominator;
	reduce();
	return *this;
}

Rational& Rational::operator*= (const Rational& b)
{
	_numerator *= b._numerator;
	_denominator *= b._denominator;
	reduce();
	return *this;
}

Rational& Rational::operator/= (const Rational& b)
{
	*this *= Rational(b._denominator, b._numerator);
	return *this;
}

bool operator== (const Rational& a, const Rational& b)
{
	return a._numerator == b._numerator && a._denominator == b._denominator;
}

bool operator!= (const Rational& a, const Rational& b)
{
	return !(a == b);
}

bool operator<= (const Rational& a, const Rational& b)
{
	return !(a > b);
}

bool operator>= (const Rational& a, const Rational& b)
{
	return !(a < b);	
}

bool operator<  (const Rational& a, const Rational& b)
{
	return a._numerator * b._denominator < a._denominator * b._numerator;
}

bool operator>  (const Rational& a, const Rational& b)
{
	return a._numerator * b._denominator > a._denominator * b._numerator;	
}
